home *** CD-ROM | disk | FTP | other *** search
- /*{{{}}}*/
- /*{{{ #includes*/
- #ifdef CONFIG_H
- # include "config.h"
- #endif
-
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <limits.h>
- #include <signal.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
-
- #define SHELL_C
- #define I_GETMSG_C
- #define I_PROMPT_C
- #define I_GETTK_C
- #define I_INIT_C
-
- #include "origami.h"
- #include <h/envvar_str.h>
- #include <lib/ori_add_lib.h>
- /*}}} */
-
- /*{{{ variables*/
- public boolean force_sh=False;
- public boolean secure=
- #ifdef SECURE
- True;
- #else
- False;
- #endif
- public char const *shell_name;
-
- #define MAX_PIPES 4
- private int p_used=0;
- private struct ph { FILE *f;pid_t id; } pipe_handle[MAX_PIPES];
- /*}}} */
-
- /*{{{ get_shell*/
- private const char *get_shell(void)
- { const char *active_shell;
- static const char bourne_shell[]=BOURNE_SHELL;
-
- if (secure)
- active_shell=shell_name;
- else if (force_sh)
- active_shell=bourne_shell;
- else
- { active_shell=getenv(SHELL);
- if (!active_shell || !active_shell[0])
- active_shell=bourne_shell;
- }
- if (active_shell && !active_shell[0])
- active_shell=0;
- return(active_shell);
- }
- /*}}} */
- /*{{{ close_pipe_f*/
- private void close_pipe_f(void)
- {
- while (p_used)
- fclose(pipe_handle[--p_used].f);
- if (rcfile)
- fclose(rcfile);
- if (msg_file>=0)
- close(msg_file);
- }
- /*}}} */
- /*{{{ flush_all*/
- private void flush_all(void) { fflush(stdout);fflush(stderr); }
- /*}}} */
- /*{{{ waitfor*/
- private int waitfor(pid_t pid)
- { int i;
- pid_t j;
-
- while (pid!=(j=waitpid(pid,&i,0)) || WIFSTOPPED(i))
- if (-1==j)
- return(-1);
- return(WIFEXITED(i) ? WEXITSTATUS(i) : -1);
- }
- /*}}} */
-
- /*{{{ subshell*/
- int subshell(const char * const cmd)
- {
- pid_t child;
- const char *active_shell;
-
- if (!(active_shell=get_shell()))
- return(EX_NOPERM);
- flush_all();
- signal(SIGINT,SIG_IGN);
- switch ((child=fork()))
- { case 0:
- /*{{{ child*/
- signal(SIGINT,SIG_DFL);
- close_pipe_f();
- execl(active_shell,active_shell,cmd?"-c":(char*)0,cmd,(char*)0);
- exit(127);
- /*}}} */
- default:
- /*{{{ wait for child*/
- { int status;
-
- status=waitfor(child);
- signal(SIGINT,ori_abort);
- return status;
- }
- /*}}} */
- case -1:
- /*{{{ fork failed*/
- msg_message(M_FORKFAIL);
- signal(SIGINT,ori_abort);
- return(-1);
- /*}}} */
- }
- }
- /*}}} */
- /*{{{ open_shell*/
- public FILE *open_shell(const char * const prog,const char * const type)
- {
- /*{{{ variables*/
- FILE *fout;
- const char *active_shell;
- int d[2];
- boolean reading;
- /*}}} */
-
- fout=0;
- if
- ( p_used<MAX_PIPES
- && (type && ((reading=(type[0]=='r')) || type[0]=='w') && type[1]=='\0')
- && (active_shell=get_shell())
- && !pipe(d)
- )
- { flush_all();
- signal(SIGINT,SIG_IGN);
- switch ((pipe_handle[p_used].id=fork()))
- { case 0:
- /*{{{ child*/
- signal(SIGINT,SIG_DFL);
- close_pipe_f();
- if (reading)
- /*{{{ stdout*/
- { int to;
-
- to=fileno(stdout);
- fclose(stdout);
- dup2(d[1],to);
- close(d[0]);
- }
- /*}}} */
- else
- /*{{{ stdin*/
- { int to;
-
- to=fileno(stdin);
- fclose(stdin);
- dup2(d[0],to);
- close(d[1]);
- }
- /*}}} */
- execl(active_shell,active_shell,"-c",prog,(char*)0);
- exit(127);
- /*}}} */
- default:
- /*{{{ setup filehandle*/
- fout=pipe_handle[p_used].f=fdopen(d[reading?0:1],type);
- if (fout)
- { close(d[reading?1:0]);
- p_used++;
- break;
- }
- else
- goto fork_fail_handling;
- /*}}} */
- case -1:
- fork_fail_handling:
- /*{{{ error, fork failed*/
- close(d[0]);
- close(d[1]);
- if (pipe_handle[p_used].id>=0)
- { kill(pipe_handle[p_used].id,SIGTERM);
- waitfor(pipe_handle[p_used].id);
- }
- msg_message(M_FORKFAIL);
- signal(SIGINT,ori_abort);
- break;
- /*}}} */
- }
- }
- return(fout);
- }
- /*}}} */
- /*{{{ close_shell*/
- public int close_shell(FILE *f)
- { struct ph *p;
-
- p=pipe_handle+MAX_PIPES;
- do
- if (f==(--p)->f)
- { int r;
-
- fclose(p->f);
- r=waitfor(p->id);
- *p=pipe_handle[--p_used];
- pipe_handle[p_used].f=0;
- return(r);
- }
- while (p!=pipe_handle);
-
- return(-1);
- }
- /*}}} */
-